﻿// <copyright file="King.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Contains a user class which represents a king (i.e. an user) in the game.</summary>

namespace Sqwarea.Persistence
{
    using System;
    using System.Drawing;
    using System.Runtime.Serialization;

    /// <summary>
    /// Class representing a user in the game point of view
    /// </summary>
    [DataContract]
    public class King : IExtensibleDataObject, ICloneable
    {
        /// <summary>
        /// Default neutral king id
        /// WARNING : when a king dead, it becomes neutral but keep its previous id for some time.
        /// To see if a king if neutral or not, please use IsNeutral extension function in Sqwarea.GameLogic.
        /// </summary>
        public const int NeutralKingId = 0;

        /// <summary>
        /// Initializes a new instance of the King class once given its Id and its owner's OpenId
        /// </summary>
        /// <param name="kingId">the Id of the king to be created</param>
        /// <param name="openId">the OpenId of the king's owner</param>
        /// <param name="nickname">the NickName of the king's owner</param>
        public King(long kingId, string openId, string nickname)
        {
            Id = kingId;
            OpenId = openId;
            Nickname = nickname;
        }

        /// <summary>
        /// Gets the Id of the king.
        /// Notice that only GameLogic.KingExtension should modify Id.
        /// </summary>
        [DataMember]
        public long Id { get; internal set; }

        /// <summary>
        /// Gets or sets the OpenId of the king's owner.
        /// Setting the OpenId is just used when the king is dead and should no more be linked to a user.
        /// </summary>
        [DataMember]
        public string OpenId { get; set; }

        /// <summary>
        /// Gets or sets the Nickname of the User.
        /// Notice it's just a copy of the Nickname of User used for performance reason when you display the map.
        /// </summary>
        [DataMember]
        public string Nickname { get; set; }

        /// <summary>
        /// Gets or sets the last date when king move.
        /// </summary>
        [DataMember]
        public DateTimeOffset LastKingMoveDate { get; set; }

        /// <summary>
        /// Gets or sets the position of the king.
        /// </summary>
        [DataMember]
        public Point Position { get; set; }

        /// <summary>
        /// Gets or sets the rectangle containing exactly all squares of the user.
        /// </summary>
        [DataMember]
        public Rectangle SquaresRectangle { get; set; }

        /// <summary>
        /// Gets or sets total number of controlled squares of the user.
        /// Useful for creating new troops.
        /// </summary>
        [DataMember]
        public int SquaresNumber { get; set; }

        /// <summary>
        /// Gets or sets extension data.
        /// </summary>
        public ExtensionDataObject ExtensionData { get; set; }

        /// <summary>
        /// Gets or sets the number of troops in the Royal Academy.
        /// WARNING : this number is not the current number. This value has been updated LastAcademyTroopsUpdate only.
        /// Sqwarea.GameLogic provides high level extensions to enable you to get real troops number.
        /// </summary>
        [DataMember]
        public int AcademyTroops { get; set; }

        /// <summary>
        /// Gets or sets the last time academy troops number has been updated.
        /// </summary>
        [DataMember]
        internal DateTimeOffset LastAcademyTroopsUpdate { get; set; }

        /// <summary>
        /// Clones the king
        /// </summary>
        /// <returns>A new king with exactly the same fields</returns>
        public object Clone()
        {
            King clone = new King(Id, OpenId, Nickname);
            clone.AcademyTroops = AcademyTroops;
            clone.LastAcademyTroopsUpdate = LastAcademyTroopsUpdate;
            clone.LastKingMoveDate = LastKingMoveDate;
            clone.Position = Position;
            clone.SquaresNumber = SquaresNumber;
            clone.SquaresRectangle = SquaresRectangle;
            return clone;
        }

        /// <summary>
        /// Verifies the equality of two kings field by field
        /// </summary>
        /// <param name="obj">The king to be compared to</param>
        /// <returns>True iff the two kings have exactly the same fields</returns>
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return base.Equals(obj);
            }

            var otherKing = (King) obj;
            return otherKing.AcademyTroops == AcademyTroops &&
                   otherKing.Id == Id &&
                   otherKing.LastAcademyTroopsUpdate == LastAcademyTroopsUpdate &&
                   otherKing.LastKingMoveDate == LastKingMoveDate &&
                   otherKing.Nickname == Nickname &&
                   otherKing.OpenId == OpenId &&
                   otherKing.Position == Position &&
                   otherKing.SquaresNumber == SquaresNumber &&
                   otherKing.SquaresRectangle == SquaresRectangle;
        }
    }
}
